'''
* This is the projet for Brtc LlmOps Platform
* @Author Leon-liao <liaosiliang@alltman.com>
* @Description //TODO 
* @File: oauth_service.py
* @Time: 2025/10/11
* @All Rights Reserve By Brtc
'''
import os
from dataclasses import dataclass
from datetime import datetime, timedelta
from typing import Any
from flask import request
from injector import inject
from internal.exception.exception import NotFoundException
from internal.model import AccountOAuth
from pkg.auth.github_oauth import GithubOAuth
from pkg.auth.oauth import OAuth
from pkg.sqlachemy.sqlalchemy import SQLAlchemy
from .jwt_service import JwtService
from .account_service import AccountService
from .base_service import BaseService



@inject
@dataclass
class OauthService(BaseService):
    db:SQLAlchemy
    jwt_service:JwtService
    account_service:AccountService

    @classmethod
    def get_all_oauth(cls)->dict[str, OAuth]:
        """获取平台所有第三方的认证服务"""
        github = GithubOAuth(
            client_id=os.getenv("GITHUB_CLIENT_ID"),
            client_secret=os.getenv("GITHUB_CLIENT_SECRET"),
            redirect_uri=os.getenv("GITHUB_REDIRECT_URI")
        )
        # 构建字典并返回
        return {
            "github":github
        }


    @classmethod
    def get_oauth_by_provider_name(cls, provider_name:str)->OAuth:
        """根据提供商名字获取提供商重定向地址"""
        all_auth = cls.get_all_oauth()
        oauth = all_auth.get(provider_name)
        if oauth is None:
            raise NotFoundException(f"授权服务{provider_name}未开发！！")
        return oauth


    def oauth_login(self, provider_name:str, code:str)->dict[str, Any]:
        """第三方OAuth授权认证登录,返回授权凭证以及过期时间"""
        #1、根据传递的provie_name获取Oauth
        oauth = self.get_oauth_by_provider_name(provider_name)
        #2、根据code 从第三方登录服务中获取 access_token
        oauth_access_token = oauth.get_access_token(code)
        #3、根据获取到的token 提取用户的信息
        oauth_user_info = oauth.get_user_info(oauth_access_token)
        #4、根据provider_name + openid 获取授权记录
        account_oauth = self.account_service.get_account_oauth_by_provider_name_and_openid(
            provider_name,
            oauth_user_info.id
        )

        if not account_oauth:
            #5、授权认证方式是 第一次登陆查询邮箱是否已经注册
            account = self.account_service.get_account_by_email(oauth_user_info.email)
            if not account:
                #6、账号不存在
                account = self.account_service.create_account(
                    name = oauth_user_info.name,
                    email = oauth_user_info.email,
                )

                #7、添加授权认证
                account_oauth = self.create(
                    AccountOAuth,
                    account_id = account.id,
                    provider = provider_name,
                    openid = oauth_user_info.id,
                    encrypted_token = oauth_access_token,
                )
        else:# 账号存在 则校验相关信息
            #8、查找账号信息
            account = self.account_service.get_account(account_oauth.account_id)
        #9、更新账号信息涵盖最后一次登陆时间
        self.update(
            account,
            last_login_at = datetime.now(),
            last_login_ip = request.remote_addr
        )
        self.update(
            account_oauth,
            encrypted_token=oauth_access_token
        )

        #10、生成授权凭证信息
        expire_at = int((datetime.now() + timedelta(days=30)).timestamp())
        payload = {
            "sub":str(account.id),
            "iss":"llmops_ai_plat",
            "exp":expire_at
        }
        access_token = self.jwt_service.generate_token(payload)

        return {
            "expire_at":expire_at,
            "access_token":access_token
        }



